﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace OrderServicePlus
{
    [Serializable]
    public class OrderService
    {
        public List<Order> orders = new List<Order>();

        public void AddOrder(Order order)
        {
            if (orders.Contains(order))
            {
                throw new Exception("Order already exists.");
            }

            foreach (var detail in order.Details)
            {
                if (order.Details.Count(d => d.Equals(detail)) > 1)
                {
                    throw new Exception("Duplicate order detail.");
                }
            }

            orders.Add(order);
        }

        public void RemoveOrder(string orderId)
        {
            var order = orders.FirstOrDefault(o => o.OrderId == orderId);
            if (order == null)
            {
                throw new Exception("Order not found.");
            }

            orders.Remove(order);
        }

        public void ModifyOrder(Order order)
        {
            var oldOrder = orders.FirstOrDefault(o => o.OrderId == order.OrderId);
            if (oldOrder == null)
            {
                throw new Exception("Order not found.");
            }

            orders.Remove(oldOrder);
            AddOrder(order);
        }
        public List<Order> QueryOrdersByOrderId(string orderId)
        {
            return orders.Where(o => o.OrderId == orderId).OrderByDescending(o => o.TotalAmount).ToList();
        }

        public List<Order> QueryOrdersByProductName(string productName)
        {
            return orders.Where(o => o.Details.Any(d => d.ProductName == productName)).OrderByDescending(o => o.TotalAmount).ToList();
        }

        public List<Order> QueryOrdersByCustomer(string customer)
        {
            return orders.Where(o => o.Customer == customer).OrderByDescending(o => o.TotalAmount).ToList();
        }

        public List<Order> QueryOrdersByAmount(double amount)
        {
            return orders.Where(o => o.TotalAmount == amount).OrderByDescending(o => o.TotalAmount).ToList();
        }

        public void Sort()
        {
            orders.Sort((o1, o2) => o1.OrderId.CompareTo(o2.OrderId));
        }

        public void Sort(Func<Order, Order, int> func)
        {
            orders.Sort((o1, o2) => func(o1, o2));
        }

        public void Export(string fileName)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(List<Order>));
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                serializer.Serialize(fs, orders);
            }
        }

        public void Import(string fileName)
        {
            XmlSerializer serializer = new XmlSerializer (typeof(List<Order>));
            using (FileStream fs = new FileStream(fileName, FileMode.Open))
            {
                orders = (List<Order>)serializer.Deserialize(fs);
            }
        }
    }

}
